Nodejs学习笔记(4) 文件操作 fs 及 express 上传

您所在的位置:网站首页 nodejs fs读取文件 Nodejs学习笔记(4) 文件操作 fs 及 express 上传

Nodejs学习笔记(4) 文件操作 fs 及 express 上传

2023-07-24 05:38| 来源: 网络整理| 查看: 265

目录参考资料1. fs 模块1.1 读取文件fs.readFile1.2 写入文件fs.writeFile1.3 获取文件信息fs.stat1.4 删除文件fs.unlink1.5 读取目录fs.readdir2. 关于 HTTP 文件传输和 multer 控制文件上传的几个问题(写在前面)2.1 文件选择后(未提交前)放在哪里?2.2 文件提交后的路径是什么?2.3 文件传输在HTTP协议中是如何进行的?

2.4 multer([options])中有哪些键?分别有什么用??

2.5 multer.array()有什么用??2.6 使用不同浏览器传输文件会有什么不同效果??3. HTML 用于上传文件的元素3.1 HTML < form > 标签的 enctype 属性3.2 HTML DOM FileUpload 对象4. express 文件上传4.1 文件上传的实例4.2 multer模块是什么?4.3 multer如何控制文件传输?4.3.1 控制编码文件的位置4.3.2 给不同的文件响应规定字段名

4.3.3 控制接收文件的类型

4.3 设置本地存储路径(通过 req 对象的属性)4.4 缓存管理

参考资料

Node.js 文件系统 | 菜鸟教程 HTML DOM FileUpload 对象 | W3school HTML 标签 | W3school HTML 标签 | W3school HTML 标签的 accept 属性 multer - npm multer模块的使用 +文件上传+ 评论 | 维克多噗噗的博客

1. fs 模块

 该模块主要执行文件操作,操作的方法均有同步和异步版本,例如读取文件内容的函数有异步的 fs.readFile() 和同步的 fs.readFileSync()。  异步的方法函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error)。其余参数根据不同的方法有所差异。  比起同步,异步方法性能更高,速度更快,而且没有阻塞。在此仅记录我在 express 上传文件操作时所用到的readFile方法、writeFile方法、stat方法和unlink方法,对其余方法仅作简单描述,详细使用方法和实例参照Node.js文件系统 | 菜鸟教程。

1.1 读取文件fs.readFile fs.readFile(filename,[,options], callback(err, data));

回调函数的参数:

err - 错误信息; data - buffer数据流对象,可用data.toString()转换成字符串; var fs = require('fs'); // 异步读取 fs.readFile('./input.txt', function (err, data) { if (err) { return console.error(err); } console.log("异步读取:" + data.toString()); }); 1.2 写入文件fs.writeFile fs.writeFile(file, data[, options], callback(err))

 writeFile 直接打开文件默认是w模式,所以如果文件存在,该方法写入的内容会覆盖旧的文件内容。

 参数使用说明如下:

file - 文件名或文件描述符。 data - 要写入文件的数据,可以是String(字符串)或Buffer(流)对象。 options - 该参数是一个对象,内容如下: encoding - 编码,默认值为utf8; mode - 模式(权限),默认值为0666(可读、可写); flag - 文件打开行为,默认值为'w'; callback - 回调函数,回调函数只包含错误信息参数(err),在写入失败时返回。

 常见的打开文件的模式(mode)有以下几种:

Flag描述 r以读取模式打开文件。如果文件不存在抛出异常。 r+ 以读写模式打开文件。如果文件不存在抛出异常。 w以写入模式打开文件,如果文件不存在则创建。 w+以读写模式打开文件,如果文件不存在则创建。 1.3 获取文件信息fs.stat fs.stat(path, callback(err, stats))

文件的状态信息包含在回调函数的参数stats中,这是一个fs.Stats对象,其内容如下:

atime: Wed Jul 25 2018 21:11:59 GMT+0800 (GMT+08:00) {} atimeMs: 1532524319921.0476 birthtime: Wed Jul 25 2018 21:11:59 GMT+0800 (GMT+08:00) {} birthtimeMs: 1532524319921.0476 blksize: undefined blocks: undefined ctime: Wed Jul 25 2018 21:11:59 GMT+0800 (GMT+08:00) {} ctimeMs: 1532524319922.0476 dev: 6533005 gid: 0 ino: 1407374884234476 mode: 33206 mtime: Wed Jul 25 2018 21:11:59 GMT+0800 (GMT+08:00) {}

 其中有四个时间值得我们关注:

atime - 访问时间(access time); birthtime - 创建时间; ctime - 状态修改时间(change time),显示的是文件的权限、拥有者、所属的组、链接数发生改变时的时间; mtime - 修改时间(modify time),显示的是文件内容被修改的最后时间。

 每一个时间都是一个JavaScript Date()对象的实例,因此有些方法是可以通用的,例如获取日期、月份、年份:

stats.birthtime.getDate() 25 stats.birthtime.getMonth() // js的月份从0开始算 6 stats.birthtime.getFullYear() 2018 1.4 删除文件fs.unlink fs.unlink(path, callback(err))

 直接删除path对应的文件,若文件不存在会通过err报错。

 其他方法

方法 作用 fs.open(path, flags[, mode], callback(err, fd)) 打开文件 fs.read(fd, buffer, offset, length, position, callback) 读取文件 fs.close(fd, callback) 关闭文件 fs.ftruncate(fd, len, callback) 截取文件 fs.mkdir(path[, mode], callback) 创建目录 fs.rmdir(path, callback) 删除目录 1.5 读取目录fs.readdir fs.readdir(path, callback(err, files))

参数说明:

path - 文件目录名(若目录不存在或者不是目录,则会将错误信息写入err); files - 目录下的文件数组列表,其包含如下字段: length - 数组大小,记录了该目录下文件和子文件夹的总数; [0, 1, 2, 3, ...] - files[i]依次记录了文件名(以及子文件夹名);

 例如我们使用如下方法输出当前目录下的所有文件及子文件夹名:

fs.readdir('./', function (err, files) { // 获取目录下所有文件名 if (err) { return console.error(err); } for (var i=0; i 标签的 enctype 属性

HTML 标签 | W3school HTML 标签 | W3school

 enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码;  默认地,表单数据会编码为 application/x-www-form-urlencoded。就是说,在发送到服务器之前,所有字符都会进行编码(空格转换为 "+" 加号,特殊符号转换为 ASCII HEX 值);  当我们使用文件上传功能时,enctype的值必须设置为multipart/form-data。

语法

属性值

值 描述 application/x-www-form-urlencoded 在发送前编码所有字符(默认) multipart/form-data

不对字符编码。

在使用包含文件上传控件的表单时,必须使用该值。

text/plain 空格转换为 "+" 加号,但不对特殊字符编码。 - - - 3.2 HTML DOM FileUpload 对象

HTML DOM FileUpload 对象 | W3school

 在 HTML 文档中 标签每出现一次,一个 FileUpload 对象就会被创建。我们可以通过使用document.getElementById()来访问 FileUpload 对象: .html:

.js(获取 FileUpload 对象):

var element = document.getElementById("uplodaFile");

FileUpload 对象的属性:

属性 描述 accept

设置或返回指示文件传输的 MIME 类型的列表(逗号分隔)。

Content-Type

accessKey 设置或返回访问 FileUpload 对象的快捷键。 alt 设置或返回不支持 时显示的替代文字。 defaultValue 设置或返回 FileUpload 对象的初始值。 disabled 设置或返回是否禁用 FileUpload 对象。 form 返回对包含 FileUpload 对象的表单的引用。 id 设置或返回 FileUpload 对象的 id。 name 设置或返回 FileUpload 对象的名称。 tabIndex 设置或返回定义 FileUpload 对象的 tab 键控制次序的索引号。 type 返回表单元素的类型。对于 FileUpload ,则是 "file" 。 value 返回由用户输入设置的文本后,FileUpload 对象的文件名。 4. express 文件上传 4.1 文件上传的实例

upload.html:

Upload Page UPLOAD IMAGE FILE var element = document.getElementById("uploadImg");

upload.js:

/** * 上传图片文件测试脚本 */ // 依赖 var express = require('express'); var app = express(); var fs = require('fs'); var bodyParser = require('body-parser'); var multer = require('multer'); // 中间件 app.use(express.static('./uploads/')); app.use(bodyParser.urlencoded({ extended: false })); // 控制允许接收的文件类型(4.3.3) function fileFilter (req, file, cd) { if (file.mimetype == "image/png" || file.mimetype == "image/jpeg"){ cd(null, true); }else{ req.error = "不允许上传" + file.mimetype + "类型的文件!"; cd(null, false); } } // 设置缓存路径和文件过滤器(4.3) var upload = multer({ dest: './uploadFiles/tmp/', fileFilter: fileFilter}); // 首页 app.get('/', function (req, res) { res.sendFile(__dirname + "/" + "upload.html"); }) // 响应请求 app.post('/image_upload', upload.array('image'), function (req, res) { // 文件信息 if(!req.files[0]){ console.log(req.error); res.send(req.error); return; }else{ console.log(req.files[0]); } // 存储并响应客户端 var des_file = __dirname + "/uploadFiles/" + req.files[0].fieldname + "/" + req.files[0].originalname; fs.readFile(req.files[0].path, function (err, data) { fs.writeFile(des_file, data, function (err) { if(err){ console.log(err); }else{ var response = { message: 'File uploaded successfully', filename: req.files[0].originalname }; console.log(response); res.json(response); } }); }); }) // 监听 var server = app.listen(3333, function () { var host = server.address().address; var port = server.address().port; console.log("应用实例,访问地址为:http://%s:%s", host, port); }) 4.2 multer模块是什么?

multer - npm

 Multer是一个专门用于处理multipart/form-data编码类型数据流的node.js中间件,在进行文件上传操作时常用到。

 需要注意的是,当表单元素的编码类型不是multipart/form-data时,Multer不会对请求进行解析。

 我们一般通过如下方法使用multer模块:

var multer = require('multer'); var upload = multer({ dest: './tmp/'}); // 响应请求 app.post('/image_upload', upload.array('image'), function (req, res) { // code... }) 4.3 multer如何控制文件传输?

multer - npm

4.3.1 控制编码文件的位置 multer({ dest: './uploadFiles/tmp/' }); 4.3.2 给不同的文件响应规定字段名 multer.array('image'); multer.array('myType');

4.3.3 控制接收文件的类型

IMME文件类型:Content-Type

前端控制

HTML 标签的 accept 属性

 为表单元素设置属性accept,限定文件选择对话框中允许选择的文件类型(多种类型用逗号分隔):

服务端控制

multer模块的使用 +文件上传+ 评论 | 维克多噗噗的博客 multer(fileFilter) - npm

 在服务端控制接收文件的类型,主要依靠multer([options])中的fileFilter键(multer的键值)。fileFilter键的使用方法是:创建一个函数fileFilter(req, file, cd){},来对请求进行解析,进而通过参数cd决定是否接收发送的文件。

 错误的使用:

// 不能直接规定fileFilter的键值 var upload = multer({ dest: '.upload', fileFilter: 'image/png, image/jpeg'});

 正确的使用:

// 控制允许接收的文件类型 function fileFilter (req, file, cd) { if (file.mimetype == "image/png" || file.mimetype == "image/jpeg"){ cd(null, true); // 同意接收文件 }else{ req.error = "不允许上传" + file.mimetype + "类型的文件!"; cd(null, false); // 拒绝接收文件 } } var upload = multer({ dest: './uploadFiles/tmp/', fileFilter: fileFilter}); file包含以下字段 encoding:"7bit"; fieldname:"image";(字段名:由upload.array('image')定义的) mimetype:"image/jpeg"; originalname:"540ff7cddc29e.jpg"; cd的用法 cd(null, true) - To accept the file pass true cd(null, false) - To reject this file pass false 4.3 设置本地存储路径(通过 req 对象的属性)

 在文件目录下创建uploadFiles文件夹,同时根据upload.array()中规定的字段名创建文件夹(一定不能创建出错,不然会提示无法打开相应的文件夹);

 例如upload.array('image'),创建uploadFiles/image,使用下面方法可以将文件存入到image文件夹中:

var des_file = __dirname + "/uploadFiles/" + req.files[0].fieldname + "/" + req.files[0].originalname; fs.readFile(req.files[0].path, function (err, data) { fs.writeFile(des_file, data, function (err) { //callback... }); }); 4.4 缓存管理

 在接收文件时,服务器将受到大量的编码文件,当完成文件接收后,这些编码的文件仍然存放在服务器主机磁盘上。这些文件的存在有利于数据的恢复,但当其数量达到一定规模时,会对磁盘空间造成较大的压力,因此,应该采取合适的手段进行编码文件的数量控制,来保证磁盘空间的可用性。

// 删除传输文件时的临时文件 var fs = require('fs'); var desDir = "D:/nodejs/my-sql/uploadFiles/tmp/"; // 先获取该文件夹下所有文件名 fs.readdir(desDir, function (err, files) { if (err) { return console.error(err); } for (var i=0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3